<!--
 * @Author: licongwei
 * @Date: 2022-03-08 15:22:29
 * @FileDescription: 地图
-->
<template>
  <div class="c-map">
    <h3 class="title">
      <!-- <p class="type">{{ isJszsBars ? '猪粮比' : type }}</p> -->
      <p class="type">{{ type }}{{ '（' + unit + '）' }}</p>
      <p class="label">区域对比</p>
      <!-- <p class="label">{{ adCodes }}</p> -->
    </h3>
    <div class="label-title" style="top: 8px; right: 24px">{{ adnames }}</div>
    <map-menu
      :state="menuState"
      style="top: 76px; left: 36px; width: 176px"
    ></map-menu>
    <charts :params="mapState.params"></charts>
    <div class="bar-chart">
      <div class="label">
        <ul class="items">
          <li
            class="item"
            v-for="(item, index) of labelState.data"
            :key="index"
          >
            <p class="name">{{ item.name }}</p>
            <p class="value">{{ item.value }}</p>
          </li>
        </ul>
      </div>
      <div class="chart">
        <charts :params="barState.params"></charts>
      </div>
    </div>
  </div>
</template>
<script lang="ts">
import { defineComponent, reactive, watch, ref } from 'vue'
import httpRequest from '@/service'
import { gradientColor } from '@/charts/utils'
import mapMenu from '@/components/mapMenu/mapMenu.vue'
interface IMenuData {
  name: string
  id: string
}
interface IMenuState {
  data: IMenuData[]
  dataSave?: IMenuData[]
  id: string
  name?: string
  getData: (id: string) => void
  handleClick: (id: string, name: string) => void
}
interface IChartState {
  params: any
  getData: (data?: any) => void
}
interface IChartDataItem {
  name: string
  value: number
  adcode: string
  unit: string
  list: IData[]
}
interface IData {
  name: string
  value: number
}
interface ILabelState {
  data: IData[]
  getData: (data?: any) => void
}
export default defineComponent({
  name: 'cMap',
  props: {
    type: {
      type: String,
      default: ''
    },
    unit: {
      type: String,
      default: ''
    },
    goodsId: {
      type: String,
      default: ''
    },
    adCodes: {
      type: String,
      default: ''
    },
    adnames: {
      type: String,
      default: ''
    },
    isJszsBars: {
      type: Boolean,
      default: false
    },
    zlbgoodsIds: {
      type: String,
      default: ''
    }
  },
  components: {
    mapMenu
  },
  setup(props, { emit }) {
    const adcode = ref('650000')
    // const adcode = ref('340000')
    const adName = ref('新疆')
    const average = ref(0)
    const menuName = ref('超市')
    // 切换菜单
    const menuState: IMenuState = reactive({
      dataSave: [],
      data: [],
      id: '',
      name: '',
      getData: () => {
        httpRequest
          .get({ url: 'M2P1MapMenu' })
          .then((res) => {
            const resArr: any = []
            res.data.forEach((item: any) => {
              // if (item.name === '监测价格') {
              //   resArr[0] = item
              // } else if (item.name === '超市价格') {
              //   resArr[1] = item
              // } else if (item.name === '批发价格') {
              //   resArr[2] = item
              // } else {
              resArr.push(item)
              // }
            })
            menuState.dataSave = JSON.parse(JSON.stringify(resArr))
            menuState.data = resArr
            menuState.id = menuState.data[0].id
            menuName.value = menuState.data[0].name
            // emit(
            //   'change',
            //   adcode.value,
            //   adName.value,
            //   menuName.value,
            //   menuState.id
            // )
            if (props.isJszsBars) {
              mapState.getData(props.zlbgoodsIds.split(',')[0])
            } else {
              if (props.goodsId) {
                mapState.getData(props.goodsId)
              }
            }
          })
          .catch(() => {
            console.log('请求失败')
          })
      },
      handleClick: (id: string, name: string) => {
        if (menuState.id === id) return
        menuState.id = id
        menuName.value = name
        emit('change', adcode.value, adName.value, menuName.value, menuState.id)
        if (props.isJszsBars) {
          mapState.getData(props.zlbgoodsIds.split(',')[0])
        } else {
          mapState.getData(props.goodsId)
        }
      }
    })

    // 地图
    const mapState: IChartState = reactive({
      params: {
        loading: true,
        chartInstance: null,
        forceRedraw: true,
        map: {
          value: '数量'
        },
        adcode: '650000',
        options: {
          dataset: {
            dimensions: [],
            source: []
          },
          dataZoom: {
            disabled: true
          },
          xAxis: {
            disabled: true
          },
          yAxis: {
            disabled: true
          },
          visualMap: [
            {
              type: 'piecewise',
              pieces: [],
              show: true,
              right: 50,
              bottom: 190,
              align: 'left',
              precision: 1,
              orient: 'vertical',
              itemWidth: 30,
              itemHeight: 15,
              showLabel: true,
              itemGap: 5,
              textStyle: {
                color: '#fff',
                fontSize: 16
              },
              outOfRange: {
                color: '#def1ff'
              }
            }
          ],
          legend: {
            show: false
          },
          tooltip: {
            show: true,
            axisPointer: {
              type: 'shadow',
              snap: true
            },
            confine: true,
            backgroundColor: '#1959a7',
            borderColor: '#4beeff',
            borderWidth: 1,
            padding: 12,
            textStyle: {
              color: '#fff',
              fontSize: 14
            },
            trigger: 'item',
            formatter: (params: any) => {
              if (params.data) {
                let listTemp = '<li style="line-height:26px;display: block;">'
                for (let item of params.data.list) {
                  if (
                    (props.isJszsBars && item.name === '超市价格') ||
                    (props.isJszsBars && item.name === '批发价格')
                  ) {
                    continue
                  }
                  listTemp += `<span style="display: inline-block;width: 50%;text-align:left;font-size:16px;color:#e8effb;">${item.name} :</span>
                          <span style="display: inline-block;width: 50%;text-align:right;font-size:16px;font-family: 'AliHYAiHei';color:#00ffea;">${item.value}</span><br/>`
                }
                listTemp += '</li>'
                return `
                    <div style="width:200px;">
                      <div style="display: flex;justify-content: space-between;">
                        <p style="color: #ffc77a;font-size:22px;line-height:40px;font-family: 'AliHYAiHei'">${
                          params.name
                        }</p>
                        <p style="color: #00ffea;font-size:16px;line-height:40px;">${
                          params.data.unit
                        }</p>
                      </div>
                      <ul>${params.data.isHide ? '' : listTemp}</ul>
                    </div>`
              }
            }
          },
          geo: [
            {
              map: '650000',
              roam: false,
              // top: '25%',
              // left: '-2%',
              top: '5.5%',
              left: '10%',
              selectedMode: true,
              // aspectScale: 0.85,
              aspectScale: 0.85,
              zoom: 1.17,
              label: {
                show: true,
                color: '#fff',
                fontSize: 18,
                fontFamily: 'AliHYAiHei',
                formatter: (params: any) => {
                  let result = ''
                  let itemdata = mapState.params.options.series[0].data.find(
                    (item: any) => {
                      return item.name == params.name
                    }
                  )
                  let value = itemdata ? itemdata.value : 0
                  result = `{name|${params.name}}\n{value|${
                    value === 0 ? '' : value
                  }}`
                  return result
                },
                rich: {
                  name: {
                    fontSize: 16,
                    lineHeight: 24,
                    fontWeight: 'normal',
                    fontFamily: 'AliHYAiHei',
                    textShadowColor: 'rgba(0,0,0,.5)',
                    textShadowBlur: 10,
                    textShadowOffsetX: 0,
                    textShadowOffsetY: 5
                  },
                  value: {
                    fontSize: 16,
                    lineHeight: 24,
                    fontWeight: 'normal',
                    fontFamily: 'AliHYAiHei',
                    color: '#ffc22f',
                    textShadowColor: 'rgba(0,0,0,.5)',
                    textShadowBlur: 5,
                    textShadowOffsetX: 0,
                    textShadowOffsetY: 0
                  }
                }
              },
              itemStyle: {
                areaColor: '#17adbc',
                borderColor: '#fff',
                borderWidth: 2,
                shadowColor: 'rgba(0,0,0,0.6)',
                shadowBlur: 10,
                shadowOffsetX: 5,
                shadowOffsetY: 5
              },
              emphasis: {
                itemStyle: {
                  areaColor: gradientColor(['#efde1f', '#ea690a']),
                  borderColor: 'rgba(255,255,255,0.8)',
                  borderWidth: 1
                },
                label: {
                  color: '#fff',
                  rich: {
                    name: {
                      fontSize: 18,
                      lineHeight: 24,
                      fontWeight: 'normal',
                      fontFamily: 'AliHYAiHei',
                      textShadowColor: 'rgba(0,0,0,.5)',
                      textShadowBlur: 10,
                      textShadowOffsetX: 0,
                      textShadowOffsetY: 5
                    },
                    value: {
                      fontSize: 20,
                      lineHeight: 24,
                      fontWeight: 'normal',
                      fontFamily: 'AliHYAiHei',
                      color: '#fff'
                    }
                  }
                }
              },
              select: {
                itemStyle: {
                  areaColor: gradientColor(['#efde1f', '#ea690a']),
                  borderColor: 'rgba(255,255,255,0.8)',
                  borderWidth: 1
                },
                label: {
                  color: '#fff',
                  rich: {
                    name: {
                      fontSize: 18,
                      lineHeight: 24,
                      fontWeight: 'normal',
                      fontFamily: 'AliHYAiHei',
                      textShadowColor: 'rgba(0,0,0,.5)',
                      textShadowBlur: 10,
                      textShadowOffsetX: 0,
                      textShadowOffsetY: 5
                    },
                    value: {
                      fontSize: 20,
                      lineHeight: 24,
                      fontWeight: 'normal',
                      fontFamily: 'AliHYAiHei',
                      color: '#fff'
                    }
                  }
                }
              },
              z: 3
            }
          ],
          series: [
            {
              type: 'map',
              map: '650000',
              geoIndex: 0,
              aspectScale: 0.85,
              data: [],
              select: {
                itemStyle: {
                  areaColor: gradientColor(['#efde1f', '#ea690a']),
                  borderColor: 'rgba(255,255,255,0.8)',
                  borderWidth: 1
                },
                label: {
                  color: '#fff',
                  rich: {
                    name: {
                      fontSize: 18,
                      lineHeight: 24,
                      fontWeight: 'normal',
                      fontFamily: 'AliHYAiHei',
                      textShadowColor: 'rgba(0,0,0,.5)',
                      textShadowBlur: 10,
                      textShadowOffsetX: 0,
                      textShadowOffsetY: 5
                    },
                    value: {
                      fontSize: 20,
                      lineHeight: 24,
                      fontWeight: 'normal',
                      fontFamily: 'AliHYAiHei',
                      color: '#fff'
                    }
                  }
                }
              }
            },
            {
              type: 'map',
              map: '650000',
              aspectScale: 0.85,
              zoom: 1.17,
              top: '6.2%',
              left: '10.7%',
              silent: true,
              itemStyle: {
                areaColor: '#064c8c',
                borderColor: 'rgba(255,255,255,0.5)',
                borderWidth: 1,
                shadowColor: 'rgba(0,0,0,1)',
                shadowBlur: 20,
                shadowOffsetX: 5,
                shadowOffsetY: 5
              }
            }
          ]
        },
        event: {
          click: (params: any) => {
            console.log(params)
            // 清除默认选中
            mapState.params.options.series[0].data.forEach((item: any) => {
              if (props.adCodes === item.adcode) {
                mapState.params.chartInstance.dispatchAction({
                  type: 'unselect',
                  seriesIndex: 0,
                  name: item.name
                })
              }
            })
            adcode.value =
              adcode.value === params.data.adcode
                ? '650000'
                : params.data.adcode
            adName.value =
              adName.value === params.data.name ? '新疆' : params.data.name
            emit(
              'change',
              adcode.value,
              adName.value,
              menuName.value,
              menuState.id
            )
          },
          customEvent: (chartInstance: any) => {
            // 保存下echarts实例
            mapState.params.chartInstance = chartInstance
            setTimeout(() => {
              // 添加默认选中
              mapState.params.options.series[0].data.forEach((item: any) => {
                if (props.adCodes === item.adcode) {
                  mapState.params.chartInstance.dispatchAction({
                    type: 'select',
                    seriesIndex: 0,
                    name: item.name
                  })
                }
              })
            }, 0)
            emit(
              'change',
              adcode.value,
              adName.value,
              menuName.value,
              menuState.id
            )
            barState.getData(mapState.params.options.series[0].data)
          }
        },
        custom: true
      },
      getData: (goodsId) => {
        mapState.params.loading = true
        httpRequest
          .get({
            url: 'M2P1Map',
            params: { menuId: menuState.id, goodsId }
          })
          .then((res) => {
            if (res.code === 200) {
              average.value = res.average
              if (res.pieces.length === 1 && !res.pieces[0].max) {
                const pie = { ...res.pieces[0], max: '10' }
                mapState.params.options.visualMap[0].pieces = [pie]
              } else {
                mapState.params.options.visualMap[0].pieces = res.pieces
              }
              res.data.forEach((i: { list: any[]; adcode: string }) => {
                if (i.list.length == 3) {
                  let obj = {
                    adcode: i.adcode,
                    name: '批发价格',
                    value: 0
                  }
                  i.list.push(obj)
                }
              })
              mapState.params.options.series[0].data = res.data
            } else {
              average.value = 0
              mapState.params.options.visualMap[0].pieces = [
                { color: '#18bed8', max: 10, min: 0 }
              ]
              mapState.params.options.series[0].data =
                mapState.params.options.series[0].data.map((i: any) => {
                  i.value = 0
                  i.isHide = true
                  return i
                })
            }
            mapState.params.loading = false
          })
          .catch(() => {
            console.log('请求失败')
          })
      }
    })

    // 柱图
    const barState: IChartState = reactive({
      params: {
        loading: true,
        map: {
          value: '价格'
        },
        options: {
          dataset: {
            dimensions: ['name', 'value'],
            source: []
          },
          grid: {
            // left: 60,
            // bottom: 0
            top: 30,
            left: 50,
            right: 50
          },
          xAxis: [
            // {
            //   // type: 'category',
            //   // position: 'right',
            //   axisTick: {
            //     show: false
            //   },
            //   axisLine: {
            //     show: false
            //   },
            //   axisLabel: {
            //     fontSize: 14,
            //     color: '#9ccfff',
            //     formatter: function (value: any) {
            //       if (value.length === 4) {
            //         return value
            //       } else {
            //         return value + '    '
            //       }
            //     }
            //   }
            // },
            {
              axisLabel: {
                interval: 0,
                fontSize: '13px',
                formatter: function (value: any) {
                  if (value.includes('地区')) {
                    const dqIndex = value.indexOf('地区')
                    return value.slice(0, dqIndex) + '\n' + value.slice(dqIndex)
                  } else if (value.length <= 3) {
                    return value
                  } else {
                    return value.slice(0, 3) + '\n' + value.slice(3)
                  }
                }
              }
            }
          ],
          // yAxis: [
          //   {
          //     type: 'value',
          //     inverse: true,
          //     show: false
          //   }
          // ],
          legend: {
            show: false
          },
          series: [
            {
              type: 'bar',
              showBackground: true,
              backgroundStyle: {
                color: 'rgba(68,156,255,0.1)'
              },
              // label: {
              //   position: ['100%', 0],
              //   offset: [-75, 0],
              //   align: 'right'
              // },
              label: {
                color: '#efdd1f',
                position: 'top',
                formatter: (item: any) => {
                  if (item.data.adcode === adcode.value) {
                    return item.data.value
                  } else {
                    return ''
                  }
                }
              },
              itemStyle: {
                color: [[['#40c4ff', '#0d66ff'], 'right']]
              },
              markLine: {
                //平均值
                symbol: 'none',
                label: {
                  show: false
                },
                data: [
                  {
                    name: '平均值',
                    type: 'average',
                    yAxis: 0
                  }
                ],
                //平均线设置
                lineStyle: {
                  //设置该线样式
                  type: 'dashed',
                  color: '#EB6F06'
                }
              },
              barWidth: 15
            }
          ]
        }
      },
      getData: (data: IChartDataItem[]) => {
        barState.params.loading = true
        barState.params.options.dataset.source = data.sort(
          (a: IChartDataItem, b: IChartDataItem) => {
            return b.value - a.value
          }
        )
        labelState.getData(data)
        barState.params.options.series[0].markLine.data[0].yAxis =
          labelState.data[0].value
        setTimeout(() => {
          barState.params.loading = false
        }, 0)
      }
    })

    // 数值展示
    const labelState: ILabelState = reactive({
      data: [],
      getData: (data: IChartDataItem[]) => {
        let maxItem: IData = {
            name: '',
            value: 0
          },
          minItem: IData = {
            name: '',
            value: 100000
          }
        data.forEach((item: IChartDataItem) => {
          if (item.value !== 0) {
            minItem = minItem.value < item.value ? minItem : item
          }
          maxItem = maxItem.value > item.value ? maxItem : item
        })

        labelState.data[0] = {
          name: '自治区平均 : ',
          value: average.value
        }
        labelState.data[1] = {
          name: '最高价格 : ' + maxItem.name,
          value: maxItem.value
        }
        labelState.data[2] = {
          name: '最低价格 : ' + minItem.name,
          value: maxItem.value > 0 ? minItem.value : 0
        }
      }
    })

    watch(
      () => props.goodsId,
      (newVal) => {
        if (menuState.id) {
          mapState.getData(newVal)
          if (menuState.data.length === 1) {
            menuState.data = JSON.parse(JSON.stringify(menuState.dataSave))
            menuState.id = menuState.data[0].id
          }
        }
      }
    )
    watch(
      () => props.zlbgoodsIds,
      (val) => {
        if (val.indexOf(',') > -1) {
          mapState.getData(val.split(',')[0])
          menuState.data = menuState.data.slice(0, 1)
        } else {
          mapState.getData(val)
          menuState.data = JSON.parse(JSON.stringify(menuState.dataSave))
        }
        menuState.id = menuState.data[0].id
      }
    )
    return {
      menuState,
      mapState,
      barState,
      labelState,
      adcode,
      menuName
    }
  }
})
</script>
<style lang="less" scoped>
.c-map {
  position: relative;
  height: 100%;
  .title {
    position: absolute;
    top: 0;
    left: 50px;
    z-index: 99;
    font-size: 20px;
    color: #ffea00;
    line-height: 30px;
    text-align: center;
  }
  .label-title {
    position: absolute;
    top: 20px;
    right: 240px;
    width: 44px;
    z-index: 99;
    padding: 30px 0;
    font-size: 26px;
    font-weight: 700;
    color: #ffc924;
    background-color: rgba(0, 71, 157, 0.8);
    border-radius: 10px;
    text-align: center;
    transition: all 0.2s;
  }
  .bar-chart {
    position: absolute;
    bottom: 0;
    left: 0;
    height: 20%;
    width: 100%;
    display: flex;
    .label {
      width: 210px;
      position: absolute;
      top: -71px;
      left: 50px;
      ul.items {
        li.item {
          display: flex;
          justify-content: space-between;
          line-height: 30px;
          &:first-child {
            p {
              color: #e3d119;
            }
          }
          p {
            font-family: 'AliHYAiHei';
            font-size: 16px;
          }
          &:nth-child(2) {
            p {
              // color: #f15e09;
              color: rgb(255, 38, 38);
            }
          }
          &:nth-child(3) {
            p {
              color: rgb(66, 255, 0);
            }
          }
        }
      }
    }
    .chart {
      flex: 1;
    }
  }
}
</style>
